{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# VAE Model\n",
    "\n",
    "Train the variational auto-encoder to mimic Phoenix temperature data."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# import libraries\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "from tensorflow.keras import layers, models\n",
    "from tensorflow.keras.optimizers import Adam\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "from helper_functions import *"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "# define constants\n",
    "INPUT_SIZE = 64*24 # dimensions of the input data\n",
    "DEGREE = 3 # degree of fourier series for seasonal inputs\n",
    "LATENT_SIZE = 4*24 # the hours associated with each latent variable"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Read Training Data\n",
    "\n",
    "See `process_data.ipynb` for the preparation of input data."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>0</th>\n",
       "      <th>1</th>\n",
       "      <th>2</th>\n",
       "      <th>3</th>\n",
       "      <th>4</th>\n",
       "      <th>5</th>\n",
       "      <th>6</th>\n",
       "      <th>7</th>\n",
       "      <th>8</th>\n",
       "      <th>9</th>\n",
       "      <th>...</th>\n",
       "      <th>1526</th>\n",
       "      <th>1527</th>\n",
       "      <th>1528</th>\n",
       "      <th>1529</th>\n",
       "      <th>1530</th>\n",
       "      <th>1531</th>\n",
       "      <th>1532</th>\n",
       "      <th>1533</th>\n",
       "      <th>1534</th>\n",
       "      <th>1535</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1975-07-31</th>\n",
       "      <td>0.964283</td>\n",
       "      <td>0.758682</td>\n",
       "      <td>0.677235</td>\n",
       "      <td>0.667352</td>\n",
       "      <td>0.664610</td>\n",
       "      <td>0.607691</td>\n",
       "      <td>0.600477</td>\n",
       "      <td>0.801750</td>\n",
       "      <td>1.029786</td>\n",
       "      <td>1.009659</td>\n",
       "      <td>...</td>\n",
       "      <td>1.320080</td>\n",
       "      <td>1.315175</td>\n",
       "      <td>1.319647</td>\n",
       "      <td>1.315680</td>\n",
       "      <td>1.320585</td>\n",
       "      <td>0.886659</td>\n",
       "      <td>0.720375</td>\n",
       "      <td>0.695270</td>\n",
       "      <td>0.405120</td>\n",
       "      <td>0.365732</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2017-08-19</th>\n",
       "      <td>0.703717</td>\n",
       "      <td>0.624205</td>\n",
       "      <td>0.521373</td>\n",
       "      <td>0.234700</td>\n",
       "      <td>0.337318</td>\n",
       "      <td>0.317850</td>\n",
       "      <td>0.227569</td>\n",
       "      <td>0.316138</td>\n",
       "      <td>0.638538</td>\n",
       "      <td>0.848409</td>\n",
       "      <td>...</td>\n",
       "      <td>0.345234</td>\n",
       "      <td>0.439151</td>\n",
       "      <td>0.485718</td>\n",
       "      <td>0.474878</td>\n",
       "      <td>0.369622</td>\n",
       "      <td>0.182857</td>\n",
       "      <td>0.012565</td>\n",
       "      <td>-0.023234</td>\n",
       "      <td>-0.123142</td>\n",
       "      <td>-0.315327</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2001-07-06</th>\n",
       "      <td>0.839117</td>\n",
       "      <td>0.792497</td>\n",
       "      <td>0.617997</td>\n",
       "      <td>0.504204</td>\n",
       "      <td>0.451051</td>\n",
       "      <td>0.428592</td>\n",
       "      <td>0.352912</td>\n",
       "      <td>0.317114</td>\n",
       "      <td>0.430974</td>\n",
       "      <td>0.341955</td>\n",
       "      <td>...</td>\n",
       "      <td>1.397530</td>\n",
       "      <td>1.493560</td>\n",
       "      <td>1.484917</td>\n",
       "      <td>1.475048</td>\n",
       "      <td>1.471033</td>\n",
       "      <td>1.442517</td>\n",
       "      <td>0.777592</td>\n",
       "      <td>0.770106</td>\n",
       "      <td>0.652979</td>\n",
       "      <td>0.604590</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2010-08-16</th>\n",
       "      <td>1.240002</td>\n",
       "      <td>1.121574</td>\n",
       "      <td>0.926427</td>\n",
       "      <td>0.802889</td>\n",
       "      <td>0.745228</td>\n",
       "      <td>0.727412</td>\n",
       "      <td>0.694128</td>\n",
       "      <td>0.678177</td>\n",
       "      <td>0.874774</td>\n",
       "      <td>0.905918</td>\n",
       "      <td>...</td>\n",
       "      <td>0.542830</td>\n",
       "      <td>0.585644</td>\n",
       "      <td>0.596969</td>\n",
       "      <td>0.592411</td>\n",
       "      <td>0.527708</td>\n",
       "      <td>0.450505</td>\n",
       "      <td>0.173873</td>\n",
       "      <td>0.086105</td>\n",
       "      <td>0.030448</td>\n",
       "      <td>-0.082456</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1987-02-22</th>\n",
       "      <td>-1.260056</td>\n",
       "      <td>-1.367588</td>\n",
       "      <td>-1.481018</td>\n",
       "      <td>-1.603712</td>\n",
       "      <td>-1.679799</td>\n",
       "      <td>-1.740936</td>\n",
       "      <td>-1.751113</td>\n",
       "      <td>-1.717562</td>\n",
       "      <td>-1.681764</td>\n",
       "      <td>-1.422338</td>\n",
       "      <td>...</td>\n",
       "      <td>1.220573</td>\n",
       "      <td>1.273707</td>\n",
       "      <td>1.275041</td>\n",
       "      <td>1.271531</td>\n",
       "      <td>1.321508</td>\n",
       "      <td>1.103985</td>\n",
       "      <td>0.782790</td>\n",
       "      <td>0.710072</td>\n",
       "      <td>0.526452</td>\n",
       "      <td>0.478230</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2006-12-11</th>\n",
       "      <td>-1.041151</td>\n",
       "      <td>-1.114603</td>\n",
       "      <td>-1.207998</td>\n",
       "      <td>-1.491556</td>\n",
       "      <td>-1.553934</td>\n",
       "      <td>-1.626629</td>\n",
       "      <td>-1.624703</td>\n",
       "      <td>-1.664318</td>\n",
       "      <td>-1.511225</td>\n",
       "      <td>-1.323540</td>\n",
       "      <td>...</td>\n",
       "      <td>-0.347897</td>\n",
       "      <td>-0.262600</td>\n",
       "      <td>-0.278471</td>\n",
       "      <td>-0.271025</td>\n",
       "      <td>-0.301563</td>\n",
       "      <td>-0.449291</td>\n",
       "      <td>-0.787470</td>\n",
       "      <td>-0.864418</td>\n",
       "      <td>-0.977245</td>\n",
       "      <td>-1.024708</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1986-06-11</th>\n",
       "      <td>0.594550</td>\n",
       "      <td>0.479838</td>\n",
       "      <td>0.578058</td>\n",
       "      <td>0.037281</td>\n",
       "      <td>0.049013</td>\n",
       "      <td>0.052298</td>\n",
       "      <td>0.092726</td>\n",
       "      <td>0.322419</td>\n",
       "      <td>0.608160</td>\n",
       "      <td>0.908048</td>\n",
       "      <td>...</td>\n",
       "      <td>1.630983</td>\n",
       "      <td>1.819980</td>\n",
       "      <td>1.831177</td>\n",
       "      <td>1.671009</td>\n",
       "      <td>1.470882</td>\n",
       "      <td>1.320167</td>\n",
       "      <td>1.211221</td>\n",
       "      <td>1.204450</td>\n",
       "      <td>1.112331</td>\n",
       "      <td>1.030068</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1992-07-29</th>\n",
       "      <td>0.912226</td>\n",
       "      <td>0.799497</td>\n",
       "      <td>0.679402</td>\n",
       "      <td>0.623579</td>\n",
       "      <td>0.602223</td>\n",
       "      <td>0.649598</td>\n",
       "      <td>0.627093</td>\n",
       "      <td>0.768274</td>\n",
       "      <td>0.969063</td>\n",
       "      <td>1.039755</td>\n",
       "      <td>...</td>\n",
       "      <td>1.437210</td>\n",
       "      <td>1.436331</td>\n",
       "      <td>1.436737</td>\n",
       "      <td>1.391794</td>\n",
       "      <td>1.193303</td>\n",
       "      <td>0.664128</td>\n",
       "      <td>0.388931</td>\n",
       "      <td>0.401096</td>\n",
       "      <td>0.255995</td>\n",
       "      <td>0.245182</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2021-04-24</th>\n",
       "      <td>-0.149637</td>\n",
       "      <td>-0.277243</td>\n",
       "      <td>-0.380983</td>\n",
       "      <td>-0.462618</td>\n",
       "      <td>-0.562222</td>\n",
       "      <td>-0.645824</td>\n",
       "      <td>-0.717425</td>\n",
       "      <td>-0.609413</td>\n",
       "      <td>-0.270531</td>\n",
       "      <td>0.006312</td>\n",
       "      <td>...</td>\n",
       "      <td>1.681876</td>\n",
       "      <td>1.736526</td>\n",
       "      <td>1.729271</td>\n",
       "      <td>1.759037</td>\n",
       "      <td>1.746629</td>\n",
       "      <td>1.683300</td>\n",
       "      <td>1.499417</td>\n",
       "      <td>1.391677</td>\n",
       "      <td>1.277088</td>\n",
       "      <td>1.138498</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1991-11-16</th>\n",
       "      <td>-1.256365</td>\n",
       "      <td>-1.275372</td>\n",
       "      <td>-1.219826</td>\n",
       "      <td>-1.323414</td>\n",
       "      <td>-1.307423</td>\n",
       "      <td>-1.380713</td>\n",
       "      <td>-1.384570</td>\n",
       "      <td>-1.386534</td>\n",
       "      <td>-1.233081</td>\n",
       "      <td>-1.154040</td>\n",
       "      <td>...</td>\n",
       "      <td>-0.578587</td>\n",
       "      <td>-0.699425</td>\n",
       "      <td>-0.720038</td>\n",
       "      <td>-0.764508</td>\n",
       "      <td>-0.745449</td>\n",
       "      <td>-0.926166</td>\n",
       "      <td>-1.133848</td>\n",
       "      <td>-1.118575</td>\n",
       "      <td>-1.187577</td>\n",
       "      <td>-1.197444</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>285 rows × 1536 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "                   0         1         2         3         4         5  \\\n",
       "1975-07-31  0.964283  0.758682  0.677235  0.667352  0.664610  0.607691   \n",
       "2017-08-19  0.703717  0.624205  0.521373  0.234700  0.337318  0.317850   \n",
       "2001-07-06  0.839117  0.792497  0.617997  0.504204  0.451051  0.428592   \n",
       "2010-08-16  1.240002  1.121574  0.926427  0.802889  0.745228  0.727412   \n",
       "1987-02-22 -1.260056 -1.367588 -1.481018 -1.603712 -1.679799 -1.740936   \n",
       "...              ...       ...       ...       ...       ...       ...   \n",
       "2006-12-11 -1.041151 -1.114603 -1.207998 -1.491556 -1.553934 -1.626629   \n",
       "1986-06-11  0.594550  0.479838  0.578058  0.037281  0.049013  0.052298   \n",
       "1992-07-29  0.912226  0.799497  0.679402  0.623579  0.602223  0.649598   \n",
       "2021-04-24 -0.149637 -0.277243 -0.380983 -0.462618 -0.562222 -0.645824   \n",
       "1991-11-16 -1.256365 -1.275372 -1.219826 -1.323414 -1.307423 -1.380713   \n",
       "\n",
       "                   6         7         8         9  ...      1526      1527  \\\n",
       "1975-07-31  0.600477  0.801750  1.029786  1.009659  ...  1.320080  1.315175   \n",
       "2017-08-19  0.227569  0.316138  0.638538  0.848409  ...  0.345234  0.439151   \n",
       "2001-07-06  0.352912  0.317114  0.430974  0.341955  ...  1.397530  1.493560   \n",
       "2010-08-16  0.694128  0.678177  0.874774  0.905918  ...  0.542830  0.585644   \n",
       "1987-02-22 -1.751113 -1.717562 -1.681764 -1.422338  ...  1.220573  1.273707   \n",
       "...              ...       ...       ...       ...  ...       ...       ...   \n",
       "2006-12-11 -1.624703 -1.664318 -1.511225 -1.323540  ... -0.347897 -0.262600   \n",
       "1986-06-11  0.092726  0.322419  0.608160  0.908048  ...  1.630983  1.819980   \n",
       "1992-07-29  0.627093  0.768274  0.969063  1.039755  ...  1.437210  1.436331   \n",
       "2021-04-24 -0.717425 -0.609413 -0.270531  0.006312  ...  1.681876  1.736526   \n",
       "1991-11-16 -1.384570 -1.386534 -1.233081 -1.154040  ... -0.578587 -0.699425   \n",
       "\n",
       "                1528      1529      1530      1531      1532      1533  \\\n",
       "1975-07-31  1.319647  1.315680  1.320585  0.886659  0.720375  0.695270   \n",
       "2017-08-19  0.485718  0.474878  0.369622  0.182857  0.012565 -0.023234   \n",
       "2001-07-06  1.484917  1.475048  1.471033  1.442517  0.777592  0.770106   \n",
       "2010-08-16  0.596969  0.592411  0.527708  0.450505  0.173873  0.086105   \n",
       "1987-02-22  1.275041  1.271531  1.321508  1.103985  0.782790  0.710072   \n",
       "...              ...       ...       ...       ...       ...       ...   \n",
       "2006-12-11 -0.278471 -0.271025 -0.301563 -0.449291 -0.787470 -0.864418   \n",
       "1986-06-11  1.831177  1.671009  1.470882  1.320167  1.211221  1.204450   \n",
       "1992-07-29  1.436737  1.391794  1.193303  0.664128  0.388931  0.401096   \n",
       "2021-04-24  1.729271  1.759037  1.746629  1.683300  1.499417  1.391677   \n",
       "1991-11-16 -0.720038 -0.764508 -0.745449 -0.926166 -1.133848 -1.118575   \n",
       "\n",
       "                1534      1535  \n",
       "1975-07-31  0.405120  0.365732  \n",
       "2017-08-19 -0.123142 -0.315327  \n",
       "2001-07-06  0.652979  0.604590  \n",
       "2010-08-16  0.030448 -0.082456  \n",
       "1987-02-22  0.526452  0.478230  \n",
       "...              ...       ...  \n",
       "2006-12-11 -0.977245 -1.024708  \n",
       "1986-06-11  1.112331  1.030068  \n",
       "1992-07-29  0.255995  0.245182  \n",
       "2021-04-24  1.277088  1.138498  \n",
       "1991-11-16 -1.187577 -1.197444  \n",
       "\n",
       "[285 rows x 1536 columns]"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data = pd.read_csv('data/processed/phoenix_64days.csv', index_col=0, parse_dates=True)\n",
    "data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Create Seasonality Data\n",
    "\n",
    "Calculate sines and cosines of earth's angle around the sun. This will be used as predictive data toward the latent prior in the form of a fourier series."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "fourier = lambda x: np.stack([np.sin(2*np.pi*i*x) for i in range(1, DEGREE+1)] + [np.cos(2*np.pi*i*x) for i in range(1, DEGREE+1)], axis=-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(285, 16, 6)"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "starting_day = np.array(data.index.dayofyear)[:, np.newaxis] - 1\n",
    "data_days = (starting_day + np.arange(0, INPUT_SIZE//24, LATENT_SIZE//24)) % 365\n",
    "seasonal_data = fourier(data_days/365)\n",
    "seasonal_data.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Separate training and testing data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "training_ratio = 0.8\n",
    "\n",
    "train = data.values[:int(len(data)*training_ratio)]\n",
    "test = data.values[int(len(data)*training_ratio):]\n",
    "train_seasonal = seasonal_data[:int(len(data)*training_ratio)]\n",
    "test_seasonal = seasonal_data[int(len(data)*training_ratio):]\n",
    "\n",
    "# convert to tensors\n",
    "train_tensor = tf.convert_to_tensor(train, dtype=tf.float32)\n",
    "test_tensor = tf.convert_to_tensor(test, dtype=tf.float32)\n",
    "train_seasonal_tensor = tf.convert_to_tensor(train_seasonal, dtype=tf.float32)\n",
    "test_seasonal_tensor = tf.convert_to_tensor(test_seasonal, dtype=tf.float32)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Define Model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Parameters\n",
    "input_shape = None #INPUT_SIZE\n",
    "latent_dim = None #INPUT_SIZE//LATENT_SIZE\n",
    "latent_filter = 10\n",
    "interim_filters = 2*latent_filter"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Encoder"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From c:\\Users\\emily\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages\\keras\\src\\backend\\tensorflow\\core.py:184: The name tf.placeholder is deprecated. Please use tf.compat.v1.placeholder instead.\n",
      "\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">Model: \"encoder\"</span>\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[1mModel: \"encoder\"\u001b[0m\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓\n",
       "┃<span style=\"font-weight: bold\"> Layer (type)        </span>┃<span style=\"font-weight: bold\"> Output Shape      </span>┃<span style=\"font-weight: bold\">    Param # </span>┃<span style=\"font-weight: bold\"> Connected to      </span>┃\n",
       "┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩\n",
       "│ input_layer         │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>)      │          <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ -                 │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">InputLayer</span>)        │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ reshape (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Reshape</span>)   │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">1</span>)   │          <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ input_layer[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>] │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ conv1d (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Conv1D</span>)     │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">20</span>)  │        <span style=\"color: #00af00; text-decoration-color: #00af00\">120</span> │ reshape[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]     │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ conv1d_1 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Conv1D</span>)   │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">20</span>)  │      <span style=\"color: #00af00; text-decoration-color: #00af00\">1,220</span> │ conv1d[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]      │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ conv1d_2 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Conv1D</span>)   │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">20</span>)  │      <span style=\"color: #00af00; text-decoration-color: #00af00\">1,220</span> │ conv1d_1[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]    │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ conv1d_3 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Conv1D</span>)   │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">20</span>)  │      <span style=\"color: #00af00; text-decoration-color: #00af00\">1,220</span> │ conv1d_2[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]    │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ conv1d_4 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Conv1D</span>)   │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">20</span>)  │      <span style=\"color: #00af00; text-decoration-color: #00af00\">1,220</span> │ conv1d_3[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]    │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ conv1d_5 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Conv1D</span>)   │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">20</span>)  │      <span style=\"color: #00af00; text-decoration-color: #00af00\">1,220</span> │ conv1d_4[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]    │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ get_item (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">GetItem</span>)  │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">10</span>)  │          <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ conv1d_5[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]    │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ get_item_1          │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">10</span>)  │          <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ conv1d_5[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]    │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">GetItem</span>)           │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ sampling (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Sampling</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">10</span>)  │          <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ get_item[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>],   │\n",
       "│                     │                   │            │ get_item_1[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]  │\n",
       "└─────────────────────┴───────────────────┴────────────┴───────────────────┘\n",
       "</pre>\n"
      ],
      "text/plain": [
       "┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓\n",
       "┃\u001b[1m \u001b[0m\u001b[1mLayer (type)       \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mOutput Shape     \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1m   Param #\u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mConnected to     \u001b[0m\u001b[1m \u001b[0m┃\n",
       "┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩\n",
       "│ input_layer         │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;45mNone\u001b[0m)      │          \u001b[38;5;34m0\u001b[0m │ -                 │\n",
       "│ (\u001b[38;5;33mInputLayer\u001b[0m)        │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ reshape (\u001b[38;5;33mReshape\u001b[0m)   │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m1\u001b[0m)   │          \u001b[38;5;34m0\u001b[0m │ input_layer[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m] │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ conv1d (\u001b[38;5;33mConv1D\u001b[0m)     │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m20\u001b[0m)  │        \u001b[38;5;34m120\u001b[0m │ reshape[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m]     │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ conv1d_1 (\u001b[38;5;33mConv1D\u001b[0m)   │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m20\u001b[0m)  │      \u001b[38;5;34m1,220\u001b[0m │ conv1d[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m]      │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ conv1d_2 (\u001b[38;5;33mConv1D\u001b[0m)   │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m20\u001b[0m)  │      \u001b[38;5;34m1,220\u001b[0m │ conv1d_1[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m]    │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ conv1d_3 (\u001b[38;5;33mConv1D\u001b[0m)   │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m20\u001b[0m)  │      \u001b[38;5;34m1,220\u001b[0m │ conv1d_2[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m]    │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ conv1d_4 (\u001b[38;5;33mConv1D\u001b[0m)   │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m20\u001b[0m)  │      \u001b[38;5;34m1,220\u001b[0m │ conv1d_3[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m]    │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ conv1d_5 (\u001b[38;5;33mConv1D\u001b[0m)   │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m20\u001b[0m)  │      \u001b[38;5;34m1,220\u001b[0m │ conv1d_4[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m]    │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ get_item (\u001b[38;5;33mGetItem\u001b[0m)  │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m10\u001b[0m)  │          \u001b[38;5;34m0\u001b[0m │ conv1d_5[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m]    │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ get_item_1          │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m10\u001b[0m)  │          \u001b[38;5;34m0\u001b[0m │ conv1d_5[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m]    │\n",
       "│ (\u001b[38;5;33mGetItem\u001b[0m)           │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ sampling (\u001b[38;5;33mSampling\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m10\u001b[0m)  │          \u001b[38;5;34m0\u001b[0m │ get_item[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m],   │\n",
       "│                     │                   │            │ get_item_1[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m]  │\n",
       "└─────────────────────┴───────────────────┴────────────┴───────────────────┘\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Total params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">6,220</span> (24.30 KB)\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[1m Total params: \u001b[0m\u001b[38;5;34m6,220\u001b[0m (24.30 KB)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">6,220</span> (24.30 KB)\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m6,220\u001b[0m (24.30 KB)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Non-trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> (0.00 B)\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[1m Non-trainable params: \u001b[0m\u001b[38;5;34m0\u001b[0m (0.00 B)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Build the encoder\n",
    "def build_encoder():\n",
    "    inputs = layers.Input(shape=(input_shape,))\n",
    "    x = layers.Reshape((-1, 1))(inputs)\n",
    "    x = layers.Conv1D(interim_filters, 5, strides=3, padding='same', activation='relu')(x)\n",
    "    x = layers.Conv1D(interim_filters, 3, strides=2, padding='same', activation='relu')(x)\n",
    "    x = layers.Conv1D(interim_filters, 3, strides=2, padding='same', activation='relu')(x)\n",
    "    x = layers.Conv1D(interim_filters, 3, strides=2, padding='same', activation='relu')(x)\n",
    "    x = layers.Conv1D(interim_filters, 3, strides=2, padding='same', activation='relu')(x)\n",
    "    x = layers.Conv1D(2*latent_filter, 3, strides=2, padding='same')(x)\n",
    "    z_mean = x[: ,:, :latent_filter]\n",
    "    z_log_var = x[:, :, latent_filter:]\n",
    "    z = Sampling()([z_mean, z_log_var])\n",
    "    encoder = models.Model(inputs, [z_mean, z_log_var, z], name='encoder')\n",
    "    encoder.summary()\n",
    "    return encoder\n",
    "\n",
    "encoder = build_encoder()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Decoder"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">Model: \"decoder\"</span>\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[1mModel: \"decoder\"\u001b[0m\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n",
       "┃<span style=\"font-weight: bold\"> Layer (type)                    </span>┃<span style=\"font-weight: bold\"> Output Shape           </span>┃<span style=\"font-weight: bold\">       Param # </span>┃\n",
       "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n",
       "│ input_layer_1 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">InputLayer</span>)      │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">10</span>)       │             <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │\n",
       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
       "│ conv1d_transpose                │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">20</span>)       │           <span style=\"color: #00af00; text-decoration-color: #00af00\">620</span> │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Conv1DTranspose</span>)               │                        │               │\n",
       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
       "│ conv1d_transpose_1              │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">20</span>)       │         <span style=\"color: #00af00; text-decoration-color: #00af00\">1,220</span> │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Conv1DTranspose</span>)               │                        │               │\n",
       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
       "│ conv1d_transpose_2              │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">20</span>)       │         <span style=\"color: #00af00; text-decoration-color: #00af00\">1,220</span> │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Conv1DTranspose</span>)               │                        │               │\n",
       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
       "│ conv1d_transpose_3              │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">20</span>)       │         <span style=\"color: #00af00; text-decoration-color: #00af00\">1,220</span> │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Conv1DTranspose</span>)               │                        │               │\n",
       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
       "│ conv1d_transpose_4              │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">20</span>)       │         <span style=\"color: #00af00; text-decoration-color: #00af00\">1,220</span> │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Conv1DTranspose</span>)               │                        │               │\n",
       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
       "│ conv1d_transpose_5              │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">1</span>)        │           <span style=\"color: #00af00; text-decoration-color: #00af00\">101</span> │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Conv1DTranspose</span>)               │                        │               │\n",
       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
       "│ reshape_1 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Reshape</span>)             │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>)           │             <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │\n",
       "└─────────────────────────────────┴────────────────────────┴───────────────┘\n",
       "</pre>\n"
      ],
      "text/plain": [
       "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n",
       "┃\u001b[1m \u001b[0m\u001b[1mLayer (type)                   \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mOutput Shape          \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1m      Param #\u001b[0m\u001b[1m \u001b[0m┃\n",
       "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n",
       "│ input_layer_1 (\u001b[38;5;33mInputLayer\u001b[0m)      │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m10\u001b[0m)       │             \u001b[38;5;34m0\u001b[0m │\n",
       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
       "│ conv1d_transpose                │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m20\u001b[0m)       │           \u001b[38;5;34m620\u001b[0m │\n",
       "│ (\u001b[38;5;33mConv1DTranspose\u001b[0m)               │                        │               │\n",
       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
       "│ conv1d_transpose_1              │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m20\u001b[0m)       │         \u001b[38;5;34m1,220\u001b[0m │\n",
       "│ (\u001b[38;5;33mConv1DTranspose\u001b[0m)               │                        │               │\n",
       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
       "│ conv1d_transpose_2              │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m20\u001b[0m)       │         \u001b[38;5;34m1,220\u001b[0m │\n",
       "│ (\u001b[38;5;33mConv1DTranspose\u001b[0m)               │                        │               │\n",
       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
       "│ conv1d_transpose_3              │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m20\u001b[0m)       │         \u001b[38;5;34m1,220\u001b[0m │\n",
       "│ (\u001b[38;5;33mConv1DTranspose\u001b[0m)               │                        │               │\n",
       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
       "│ conv1d_transpose_4              │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m20\u001b[0m)       │         \u001b[38;5;34m1,220\u001b[0m │\n",
       "│ (\u001b[38;5;33mConv1DTranspose\u001b[0m)               │                        │               │\n",
       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
       "│ conv1d_transpose_5              │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m1\u001b[0m)        │           \u001b[38;5;34m101\u001b[0m │\n",
       "│ (\u001b[38;5;33mConv1DTranspose\u001b[0m)               │                        │               │\n",
       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
       "│ reshape_1 (\u001b[38;5;33mReshape\u001b[0m)             │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;45mNone\u001b[0m)           │             \u001b[38;5;34m0\u001b[0m │\n",
       "└─────────────────────────────────┴────────────────────────┴───────────────┘\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Total params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">5,601</span> (21.88 KB)\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[1m Total params: \u001b[0m\u001b[38;5;34m5,601\u001b[0m (21.88 KB)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">5,601</span> (21.88 KB)\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m5,601\u001b[0m (21.88 KB)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Non-trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> (0.00 B)\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[1m Non-trainable params: \u001b[0m\u001b[38;5;34m0\u001b[0m (0.00 B)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Build the decoder\n",
    "def build_decoder():\n",
    "    latent_inputs = layers.Input(shape=(latent_dim, latent_filter))\n",
    "    x = layers.Conv1DTranspose(interim_filters, 3, strides=2, padding='same', activation='relu')(latent_inputs)\n",
    "    x = layers.Conv1DTranspose(interim_filters, 3, strides=2, padding='same', activation='relu')(x)\n",
    "    x = layers.Conv1DTranspose(interim_filters, 3, strides=2, padding='same', activation='relu')(x)\n",
    "    x = layers.Conv1DTranspose(interim_filters, 3, strides=2, padding='same', activation='relu')(x)\n",
    "    x = layers.Conv1DTranspose(interim_filters, 3, strides=2, padding='same', activation='relu')(x)\n",
    "    x = layers.Conv1DTranspose(1, 5, strides=3, padding='same')(x)\n",
    "    outputs = layers.Reshape((-1,))(x)\n",
    "    decoder = models.Model(latent_inputs, outputs, name='decoder')\n",
    "    decoder.summary()\n",
    "    return decoder\n",
    "\n",
    "decoder = build_decoder()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Prior"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">Model: \"seasonal_prior\"</span>\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[1mModel: \"seasonal_prior\"\u001b[0m\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓\n",
       "┃<span style=\"font-weight: bold\"> Layer (type)        </span>┃<span style=\"font-weight: bold\"> Output Shape      </span>┃<span style=\"font-weight: bold\">    Param # </span>┃<span style=\"font-weight: bold\"> Connected to      </span>┃\n",
       "┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩\n",
       "│ input_layer_2       │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">6</span>)   │          <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ -                 │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">InputLayer</span>)        │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ dense (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>)       │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">20</span>)  │        <span style=\"color: #00af00; text-decoration-color: #00af00\">120</span> │ input_layer_2[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]… │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ get_item_2          │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">10</span>)  │          <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ dense[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]       │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">GetItem</span>)           │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ get_item_3          │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">10</span>)  │          <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ dense[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]       │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">GetItem</span>)           │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ sampling_1          │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">10</span>)  │          <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ get_item_2[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>], │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Sampling</span>)          │                   │            │ get_item_3[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]  │\n",
       "└─────────────────────┴───────────────────┴────────────┴───────────────────┘\n",
       "</pre>\n"
      ],
      "text/plain": [
       "┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓\n",
       "┃\u001b[1m \u001b[0m\u001b[1mLayer (type)       \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mOutput Shape     \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1m   Param #\u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mConnected to     \u001b[0m\u001b[1m \u001b[0m┃\n",
       "┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩\n",
       "│ input_layer_2       │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m6\u001b[0m)   │          \u001b[38;5;34m0\u001b[0m │ -                 │\n",
       "│ (\u001b[38;5;33mInputLayer\u001b[0m)        │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ dense (\u001b[38;5;33mDense\u001b[0m)       │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m20\u001b[0m)  │        \u001b[38;5;34m120\u001b[0m │ input_layer_2[\u001b[38;5;34m0\u001b[0m]… │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ get_item_2          │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m10\u001b[0m)  │          \u001b[38;5;34m0\u001b[0m │ dense[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m]       │\n",
       "│ (\u001b[38;5;33mGetItem\u001b[0m)           │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ get_item_3          │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m10\u001b[0m)  │          \u001b[38;5;34m0\u001b[0m │ dense[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m]       │\n",
       "│ (\u001b[38;5;33mGetItem\u001b[0m)           │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ sampling_1          │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m10\u001b[0m)  │          \u001b[38;5;34m0\u001b[0m │ get_item_2[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m], │\n",
       "│ (\u001b[38;5;33mSampling\u001b[0m)          │                   │            │ get_item_3[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m]  │\n",
       "└─────────────────────┴───────────────────┴────────────┴───────────────────┘\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Total params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">120</span> (480.00 B)\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[1m Total params: \u001b[0m\u001b[38;5;34m120\u001b[0m (480.00 B)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">120</span> (480.00 B)\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m120\u001b[0m (480.00 B)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Non-trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> (0.00 B)\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[1m Non-trainable params: \u001b[0m\u001b[38;5;34m0\u001b[0m (0.00 B)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "def build_seasonal_prior():\n",
    "    seasonal_inputs = layers.Input(shape=(latent_dim, 2*DEGREE,))\n",
    "    x = layers.Dense(2*latent_filter, use_bias=False)(seasonal_inputs)\n",
    "    z_mean = x[:, :, :latent_filter]\n",
    "    z_log_var = x[:, :, latent_filter:]\n",
    "    z = Sampling()([z_mean, z_log_var])\n",
    "    seasonal_prior = models.Model(seasonal_inputs, [z_mean, z_log_var, z], name='seasonal_prior')\n",
    "    seasonal_prior.summary()\n",
    "    return seasonal_prior\n",
    "\n",
    "seasonal_prior = build_seasonal_prior()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Overall Model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "class VAE(models.Model):\n",
    "    def __init__(self, encoder, decoder, prior, **kwargs):\n",
    "        super(VAE, self).__init__(**kwargs)\n",
    "        self.encoder = encoder\n",
    "        self.decoder = decoder\n",
    "        self.prior = prior\n",
    "        self.noise_log_var = self.add_weight(name='var', shape=(1,), initializer='zeros', trainable=True)\n",
    "\n",
    "    @tf.function\n",
    "    def vae_loss(self, data):\n",
    "        values, seasonal = data\n",
    "        z_mean, z_log_var, z = self.encoder(values)\n",
    "        reconstructed = self.decoder(z)\n",
    "        reconstruction_loss = -log_lik_normal_sum(values, reconstructed, self.noise_log_var)/INPUT_SIZE\n",
    "        seasonal_z_mean, seasonal_z_log_var, _ = self.prior(seasonal)\n",
    "        kl_loss_z = kl_divergence_sum(z_mean, z_log_var, seasonal_z_mean, seasonal_z_log_var)/INPUT_SIZE\n",
    "        return reconstruction_loss, kl_loss_z\n",
    "\n",
    "    def train_step(self, data):\n",
    "        with tf.GradientTape() as tape:\n",
    "            reconstruction_loss, kl_loss_z = self.vae_loss(data)\n",
    "            total_loss = reconstruction_loss + kl_loss_z\n",
    "        \n",
    "        gradients = tape.gradient(total_loss, self.trainable_variables)\n",
    "        self.optimizer.apply_gradients(zip(gradients, self.trainable_variables))\n",
    "        \n",
    "        return {'loss': total_loss}\n",
    "    \n",
    "    def test_step(self, data):\n",
    "        reconstruction_loss, kl_loss_z = self.vae_loss(data)\n",
    "\n",
    "        return {'loss': reconstruction_loss + kl_loss_z, 'recon': reconstruction_loss, 'kl': kl_loss_z}\n",
    "\n",
    "    def call(self, inputs):\n",
    "        _, _, z = self.encoder(inputs)\n",
    "        reconstructed = self.decoder(z)\n",
    "        return reconstructed\n",
    "\n",
    "vae = VAE(encoder=encoder, decoder=decoder, prior=seasonal_prior)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Train Model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "learning_rate = 0.001\n",
    "\n",
    "optimizer = Adam(learning_rate=learning_rate)\n",
    "\n",
    "vae.compile(optimizer=optimizer)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 15ms/step - loss: -0.6181 - val_kl: 0.1395 - val_loss: -0.6542 - val_recon: -0.7937\n",
      "Epoch 2/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 11ms/step - loss: -0.6052 - val_kl: 0.1405 - val_loss: -0.6630 - val_recon: -0.8035\n",
      "Epoch 3/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 11ms/step - loss: -0.6056 - val_kl: 0.1413 - val_loss: -0.6607 - val_recon: -0.8021\n",
      "Epoch 4/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 12ms/step - loss: -0.6116 - val_kl: 0.1402 - val_loss: -0.6638 - val_recon: -0.8041\n",
      "Epoch 5/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 11ms/step - loss: -0.6079 - val_kl: 0.1411 - val_loss: -0.6593 - val_recon: -0.8004\n",
      "Epoch 6/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 11ms/step - loss: -0.6132 - val_kl: 0.1411 - val_loss: -0.6601 - val_recon: -0.8011\n",
      "Epoch 7/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 11ms/step - loss: -0.6116 - val_kl: 0.1413 - val_loss: -0.6612 - val_recon: -0.8025\n",
      "Epoch 8/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 11ms/step - loss: -0.6104 - val_kl: 0.1412 - val_loss: -0.6656 - val_recon: -0.8068\n",
      "Epoch 9/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 11ms/step - loss: -0.6160 - val_kl: 0.1413 - val_loss: -0.6638 - val_recon: -0.8051\n",
      "Epoch 10/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 13ms/step - loss: -0.6093 - val_kl: 0.1417 - val_loss: -0.6661 - val_recon: -0.8079\n",
      "Epoch 11/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 11ms/step - loss: -0.6087 - val_kl: 0.1407 - val_loss: -0.6655 - val_recon: -0.8061\n",
      "Epoch 12/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 11ms/step - loss: -0.6153 - val_kl: 0.1417 - val_loss: -0.6625 - val_recon: -0.8042\n",
      "Epoch 13/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 11ms/step - loss: -0.6059 - val_kl: 0.1427 - val_loss: -0.6630 - val_recon: -0.8057\n",
      "Epoch 14/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 11ms/step - loss: -0.6165 - val_kl: 0.1430 - val_loss: -0.6661 - val_recon: -0.8091\n",
      "Epoch 15/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 11ms/step - loss: -0.6205 - val_kl: 0.1427 - val_loss: -0.6621 - val_recon: -0.8047\n",
      "Epoch 16/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 11ms/step - loss: -0.6216 - val_kl: 0.1420 - val_loss: -0.6612 - val_recon: -0.8032\n",
      "Epoch 17/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 12ms/step - loss: -0.6186 - val_kl: 0.1418 - val_loss: -0.6632 - val_recon: -0.8050\n",
      "Epoch 18/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 13ms/step - loss: -0.6011 - val_kl: 0.1431 - val_loss: -0.6572 - val_recon: -0.8003\n",
      "Epoch 19/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 12ms/step - loss: -0.6066 - val_kl: 0.1430 - val_loss: -0.6593 - val_recon: -0.8023\n",
      "Epoch 20/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 12ms/step - loss: -0.6112 - val_kl: 0.1434 - val_loss: -0.6625 - val_recon: -0.8060\n",
      "Epoch 21/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 11ms/step - loss: -0.6114 - val_kl: 0.1442 - val_loss: -0.6617 - val_recon: -0.8059\n",
      "Epoch 22/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 12ms/step - loss: -0.6167 - val_kl: 0.1435 - val_loss: -0.6661 - val_recon: -0.8096\n",
      "Epoch 23/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 12ms/step - loss: -0.6150 - val_kl: 0.1432 - val_loss: -0.6651 - val_recon: -0.8082\n",
      "Epoch 24/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 12ms/step - loss: -0.6180 - val_kl: 0.1428 - val_loss: -0.6658 - val_recon: -0.8086\n",
      "Epoch 25/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 12ms/step - loss: -0.6272 - val_kl: 0.1437 - val_loss: -0.6675 - val_recon: -0.8112\n",
      "Epoch 26/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 14ms/step - loss: -0.6167 - val_kl: 0.1435 - val_loss: -0.6639 - val_recon: -0.8074\n",
      "Epoch 27/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 11ms/step - loss: -0.6253 - val_kl: 0.1442 - val_loss: -0.6661 - val_recon: -0.8103\n",
      "Epoch 28/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 11ms/step - loss: -0.6172 - val_kl: 0.1448 - val_loss: -0.6645 - val_recon: -0.8093\n",
      "Epoch 29/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 12ms/step - loss: -0.6051 - val_kl: 0.1442 - val_loss: -0.6625 - val_recon: -0.8067\n",
      "Epoch 30/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 12ms/step - loss: -0.6133 - val_kl: 0.1442 - val_loss: -0.6569 - val_recon: -0.8011\n",
      "Epoch 31/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 11ms/step - loss: -0.6109 - val_kl: 0.1449 - val_loss: -0.6665 - val_recon: -0.8114\n",
      "Epoch 32/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 11ms/step - loss: -0.6126 - val_kl: 0.1451 - val_loss: -0.6609 - val_recon: -0.8060\n",
      "Epoch 33/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 11ms/step - loss: -0.6205 - val_kl: 0.1452 - val_loss: -0.6727 - val_recon: -0.8178\n",
      "Epoch 34/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 11ms/step - loss: -0.6160 - val_kl: 0.1454 - val_loss: -0.6671 - val_recon: -0.8126\n",
      "Epoch 35/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 12ms/step - loss: -0.6190 - val_kl: 0.1458 - val_loss: -0.6684 - val_recon: -0.8142\n",
      "Epoch 36/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 12ms/step - loss: -0.6082 - val_kl: 0.1447 - val_loss: -0.6689 - val_recon: -0.8135\n",
      "Epoch 37/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 12ms/step - loss: -0.6223 - val_kl: 0.1460 - val_loss: -0.6711 - val_recon: -0.8171\n",
      "Epoch 38/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 12ms/step - loss: -0.6179 - val_kl: 0.1463 - val_loss: -0.6616 - val_recon: -0.8079\n",
      "Epoch 39/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 12ms/step - loss: -0.6197 - val_kl: 0.1458 - val_loss: -0.6686 - val_recon: -0.8144\n",
      "Epoch 40/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 12ms/step - loss: -0.6266 - val_kl: 0.1451 - val_loss: -0.6672 - val_recon: -0.8122\n",
      "Epoch 41/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 12ms/step - loss: -0.6231 - val_kl: 0.1460 - val_loss: -0.6703 - val_recon: -0.8163\n",
      "Epoch 42/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 13ms/step - loss: -0.6179 - val_kl: 0.1453 - val_loss: -0.6619 - val_recon: -0.8073\n",
      "Epoch 43/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 12ms/step - loss: -0.6164 - val_kl: 0.1447 - val_loss: -0.6685 - val_recon: -0.8131\n",
      "Epoch 44/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 12ms/step - loss: -0.6311 - val_kl: 0.1456 - val_loss: -0.6660 - val_recon: -0.8116\n",
      "Epoch 45/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 11ms/step - loss: -0.6244 - val_kl: 0.1452 - val_loss: -0.6689 - val_recon: -0.8141\n",
      "Epoch 46/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 13ms/step - loss: -0.6212 - val_kl: 0.1456 - val_loss: -0.6721 - val_recon: -0.8177\n",
      "Epoch 47/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 15ms/step - loss: -0.6229 - val_kl: 0.1463 - val_loss: -0.6755 - val_recon: -0.8218\n",
      "Epoch 48/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 16ms/step - loss: -0.6231 - val_kl: 0.1474 - val_loss: -0.6684 - val_recon: -0.8158\n",
      "Epoch 49/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 16ms/step - loss: -0.6324 - val_kl: 0.1459 - val_loss: -0.6702 - val_recon: -0.8160\n",
      "Epoch 50/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 17ms/step - loss: -0.6155 - val_kl: 0.1457 - val_loss: -0.6710 - val_recon: -0.8167\n",
      "Epoch 51/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 17ms/step - loss: -0.6206 - val_kl: 0.1472 - val_loss: -0.6753 - val_recon: -0.8225\n",
      "Epoch 52/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 17ms/step - loss: -0.6279 - val_kl: 0.1473 - val_loss: -0.6687 - val_recon: -0.8160\n",
      "Epoch 53/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 17ms/step - loss: -0.6274 - val_kl: 0.1475 - val_loss: -0.6764 - val_recon: -0.8239\n",
      "Epoch 54/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 16ms/step - loss: -0.6301 - val_kl: 0.1465 - val_loss: -0.6760 - val_recon: -0.8225\n",
      "Epoch 55/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 16ms/step - loss: -0.6255 - val_kl: 0.1475 - val_loss: -0.6736 - val_recon: -0.8211\n",
      "Epoch 56/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 16ms/step - loss: -0.6241 - val_kl: 0.1484 - val_loss: -0.6697 - val_recon: -0.8181\n",
      "Epoch 57/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 19ms/step - loss: -0.6222 - val_kl: 0.1480 - val_loss: -0.6753 - val_recon: -0.8233\n",
      "Epoch 58/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 17ms/step - loss: -0.6120 - val_kl: 0.1456 - val_loss: -0.6673 - val_recon: -0.8129\n",
      "Epoch 59/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 18ms/step - loss: -0.6054 - val_kl: 0.1475 - val_loss: -0.6694 - val_recon: -0.8170\n",
      "Epoch 60/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 17ms/step - loss: -0.6301 - val_kl: 0.1482 - val_loss: -0.6753 - val_recon: -0.8235\n",
      "Epoch 61/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 16ms/step - loss: -0.6176 - val_kl: 0.1471 - val_loss: -0.6720 - val_recon: -0.8191\n",
      "Epoch 62/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 17ms/step - loss: -0.6099 - val_kl: 0.1473 - val_loss: -0.6712 - val_recon: -0.8184\n",
      "Epoch 63/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 18ms/step - loss: -0.6219 - val_kl: 0.1465 - val_loss: -0.6681 - val_recon: -0.8146\n",
      "Epoch 64/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 20ms/step - loss: -0.6211 - val_kl: 0.1476 - val_loss: -0.6735 - val_recon: -0.8211\n",
      "Epoch 65/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 23ms/step - loss: -0.6278 - val_kl: 0.1477 - val_loss: -0.6664 - val_recon: -0.8141\n",
      "Epoch 66/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 23ms/step - loss: -0.6293 - val_kl: 0.1474 - val_loss: -0.6714 - val_recon: -0.8188\n",
      "Epoch 67/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 24ms/step - loss: -0.6286 - val_kl: 0.1472 - val_loss: -0.6759 - val_recon: -0.8232\n",
      "Epoch 68/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 27ms/step - loss: -0.6300 - val_kl: 0.1479 - val_loss: -0.6753 - val_recon: -0.8232\n",
      "Epoch 69/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 27ms/step - loss: -0.6236 - val_kl: 0.1489 - val_loss: -0.6673 - val_recon: -0.8162\n",
      "Epoch 70/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 27ms/step - loss: -0.6198 - val_kl: 0.1484 - val_loss: -0.6757 - val_recon: -0.8241\n",
      "Epoch 71/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 27ms/step - loss: -0.6310 - val_kl: 0.1481 - val_loss: -0.6736 - val_recon: -0.8218\n",
      "Epoch 72/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 24ms/step - loss: -0.6223 - val_kl: 0.1478 - val_loss: -0.6721 - val_recon: -0.8199\n",
      "Epoch 73/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 13ms/step - loss: -0.6222 - val_kl: 0.1475 - val_loss: -0.6727 - val_recon: -0.8202\n",
      "Epoch 74/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 13ms/step - loss: -0.6354 - val_kl: 0.1480 - val_loss: -0.6702 - val_recon: -0.8182\n",
      "Epoch 75/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 13ms/step - loss: -0.6235 - val_kl: 0.1484 - val_loss: -0.6784 - val_recon: -0.8268\n",
      "Epoch 76/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 15ms/step - loss: -0.6354 - val_kl: 0.1488 - val_loss: -0.6786 - val_recon: -0.8274\n",
      "Epoch 77/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 15ms/step - loss: -0.6239 - val_kl: 0.1490 - val_loss: -0.6803 - val_recon: -0.8293\n",
      "Epoch 78/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 15ms/step - loss: -0.6301 - val_kl: 0.1500 - val_loss: -0.6764 - val_recon: -0.8263\n",
      "Epoch 79/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 16ms/step - loss: -0.6364 - val_kl: 0.1486 - val_loss: -0.6812 - val_recon: -0.8298\n",
      "Epoch 80/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 16ms/step - loss: -0.6325 - val_kl: 0.1488 - val_loss: -0.6781 - val_recon: -0.8269\n",
      "Epoch 81/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 16ms/step - loss: -0.6375 - val_kl: 0.1496 - val_loss: -0.6790 - val_recon: -0.8286\n",
      "Epoch 82/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 18ms/step - loss: -0.6351 - val_kl: 0.1482 - val_loss: -0.6795 - val_recon: -0.8277\n",
      "Epoch 83/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 16ms/step - loss: -0.6385 - val_kl: 0.1490 - val_loss: -0.6858 - val_recon: -0.8348\n",
      "Epoch 84/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 17ms/step - loss: -0.6327 - val_kl: 0.1494 - val_loss: -0.6810 - val_recon: -0.8304\n",
      "Epoch 85/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 17ms/step - loss: -0.6316 - val_kl: 0.1503 - val_loss: -0.6728 - val_recon: -0.8231\n",
      "Epoch 86/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 17ms/step - loss: -0.6291 - val_kl: 0.1503 - val_loss: -0.6761 - val_recon: -0.8264\n",
      "Epoch 87/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 16ms/step - loss: -0.6254 - val_kl: 0.1513 - val_loss: -0.6817 - val_recon: -0.8330\n",
      "Epoch 88/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 16ms/step - loss: -0.6235 - val_kl: 0.1509 - val_loss: -0.6747 - val_recon: -0.8256\n",
      "Epoch 89/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 16ms/step - loss: -0.6280 - val_kl: 0.1494 - val_loss: -0.6728 - val_recon: -0.8222\n",
      "Epoch 90/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 16ms/step - loss: -0.6389 - val_kl: 0.1501 - val_loss: -0.6756 - val_recon: -0.8257\n",
      "Epoch 91/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 16ms/step - loss: -0.6362 - val_kl: 0.1515 - val_loss: -0.6804 - val_recon: -0.8319\n",
      "Epoch 92/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 16ms/step - loss: -0.6198 - val_kl: 0.1503 - val_loss: -0.6813 - val_recon: -0.8316\n",
      "Epoch 93/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 17ms/step - loss: -0.6326 - val_kl: 0.1493 - val_loss: -0.6770 - val_recon: -0.8264\n",
      "Epoch 94/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 20ms/step - loss: -0.6300 - val_kl: 0.1497 - val_loss: -0.6798 - val_recon: -0.8295\n",
      "Epoch 95/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 18ms/step - loss: -0.6375 - val_kl: 0.1507 - val_loss: -0.6780 - val_recon: -0.8287\n",
      "Epoch 96/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 16ms/step - loss: -0.6341 - val_kl: 0.1505 - val_loss: -0.6840 - val_recon: -0.8345\n",
      "Epoch 97/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 16ms/step - loss: -0.6415 - val_kl: 0.1510 - val_loss: -0.6787 - val_recon: -0.8298\n",
      "Epoch 98/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 16ms/step - loss: -0.6353 - val_kl: 0.1505 - val_loss: -0.6849 - val_recon: -0.8354\n",
      "Epoch 99/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 16ms/step - loss: -0.6334 - val_kl: 0.1504 - val_loss: -0.6788 - val_recon: -0.8292\n",
      "Epoch 100/100\n",
      "\u001b[1m8/8\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 16ms/step - loss: -0.6339 - val_kl: 0.1508 - val_loss: -0.6810 - val_recon: -0.8318\n"
     ]
    }
   ],
   "source": [
    "epochs = 100\n",
    "\n",
    "batch_size = 32\n",
    "\n",
    "history = vae.fit(\n",
    "    train_tensor, train_seasonal_tensor, \n",
    "    epochs=epochs,\n",
    "    batch_size=batch_size,\n",
    "    validation_data=(test_tensor, test_seasonal_tensor),\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Model Results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "noise emission sigma:  0.102324024\n"
     ]
    }
   ],
   "source": [
    "# Model reconstruction accuracy\n",
    "print('noise emission sigma: ', np.exp(0.5*vae.noise_log_var)[0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Reconstruction loss:  -0.8494765\n",
      "KL loss:              0.14912993\n",
      "Total loss:           -0.7003466\n"
     ]
    }
   ],
   "source": [
    "# Loss on validation data\n",
    "\n",
    "recon_loss, kl_loss = vae.vae_loss((test_tensor, test_seasonal_tensor))\n",
    "recon_loss = recon_loss.numpy()\n",
    "kl_loss = kl_loss.numpy()\n",
    "total_loss = recon_loss + kl_loss\n",
    "\n",
    "print('Reconstruction loss: ', recon_loss)\n",
    "print('KL loss:             ', kl_loss)\n",
    "print('Total loss:          ', total_loss)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Review latent variables"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAABLwAAAHDCAYAAAAukwOJAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy80BEi2AAAACXBIWXMAAA9hAAAPYQGoP6dpAACNhUlEQVR4nOzde1yUdfr/8feAMoICmoJimihqkLoVaBrKhtZ2kg0WsYOyX23T3Mx2C7QVO7qVZB5qO2jWrzV3LdsNUTfNjmqRq5tCh6WFRAs1xfMBFAQZ5veHO7OMoM4gc+T1fDzm4cx9Xzf3dXPynovP5/oYzGazWQAAAAAAAICP8HN3AgAAAAAAAEBzouAFAAAAAAAAn0LBCwAAAAAAAD6FghcAAAAAAAB8CgUvAAAAAAAA+BQKXgAAAAAAAPApFLwAAAAAAADgUyh4AQAAAAAAwKdQ8AIAAAAAAIBPoeAFwO3efPNNGQwGlZaWNtvHHD9+vCIjI5vt4wEAAHgz7rdcLzExUYmJie5OA2ixKHgBPsRyI3Oux+bNm92dosdJTEyUwWBQnz59Gt3/8ccfWz9/OTk5Ls4OAAB4Gu63HJeYmKj+/fu7NYeCggIZDAY9+uij54wpKSmRwWBQRkaGCzMD4Cyt3J0AgOb3xz/+UT179mywvXfv3m7IxvO1adNG27dv15dffqlrrrnGZt9bb72lNm3a6NSpU27KDgAAeCLut7xLbGysoqOjtWzZMj399NONxrz99tuSpPT09GY550cffdQsHwdA01DwAnzQLbfcooEDB7o7Da8RFRWl2tpaLVu2zKbgderUKa1YsUIjR47U8uXL3ZghAADwNNxveZ+xY8fqscce0+bNmzVkyJAG+5ctW6bo6GjFxsZe1HkqKysVFBSkgICAi/o4AC4OUxqBFqi0tFQGg0Fz587Va6+9pqioKBmNRg0aNEhbtmxpEF9cXKzbb79dYWFhCgwM1OWXX65HHnnEJuarr77SLbfcopCQELVr107XX399o0P6v/vuO40YMUKBgYHq1q2bnn76adXV1TWa59q1a5WQkKC2bdsqODhYI0eO1HfffdcgbuXKlerfv7/atGmj/v37a8WKFQ5/Tu666y797W9/s8nlvffeU2VlpW6//fZGj9mzZ49+85vfqHPnzjIajerXr5/+/Oc/28TU1NTo8ccfV1xcnEJDQ9W2bVslJCRo/fr1NnGOfk0AAIBn437LcQsWLFC/fv1kNBrVtWtX3X///Tp27FiDuFdeeUW9evVSYGCgrrnmGuXl5dnVL2vs2LGS/jeSq778/Hx9//331phVq1Zp5MiR6tq1q4xGo6KiovTUU0/JZDLZHGeZrpmfn6+f//znCgoK0owZM6z76ufkrPtCe7537LlvBXwNI7wAH3T8+HEdOnTIZpvBYFDHjh1ttr399tuqqKjQpEmTZDAY9Nxzzyk1NVU//PCDWrduLUn69ttvlZCQoNatW+vee+9VZGSkduzYoffee0/PPPOMpDM3VQkJCQoJCdHDDz+s1q1ba9GiRUpMTNRnn32mwYMHS5L27dun4cOHq7a2VtOnT1fbtm312muvKTAwsME1/PWvf9W4ceN00003afbs2aqsrNTChQs1bNgwffXVV9YGqR999JFGjRqlK664QtnZ2Tp8+LDuvvtudevWzaHP2ZgxY/Tkk09qw4YNGjFihPXzc/311ys8PLxB/P79+zVkyBAZDAZNmTJFYWFhWrt2re655x6Vl5frwQcflCSVl5fr//2//6e77rpLEydOVEVFhd544w3ddNNN+vLLL3XVVVc5/DUBAADux/2W4/db5/Pkk09q5syZuuGGG3Tffffp+++/18KFC7VlyxZt3LjR+rlauHChpkyZooSEBD300EMqLS1VSkqKOnTocMF8evbsqfj4eP3973/X888/L39/f+s+SxFszJgxks70amvXrp0yMjLUrl07rVu3To8//rjKy8s1Z84cm497+PBh3XLLLbrzzjuVnp6uzp07N3p+Z9wX2vO9Y+99K+BzzAB8xuLFi82SGn0YjUZr3I8//miWZO7YsaP5yJEj1u2rVq0ySzK/99571m0///nPzcHBweadO3fanKuurs76PCUlxRwQEGDesWOHddvevXvNwcHB5p///OfWbQ8++KBZkvlf//qXdduBAwfMoaGhZknmH3/80Ww2m80VFRXm9u3bmydOnGhzzn379plDQ0Nttl911VXmiIgI87Fjx6zbPvroI7Mkc48ePS74ObvuuuvM/fr1M5vNZvPAgQPN99xzj9lsNpuPHj1qDggIMC9ZssS8fv16syTzu+++az3unnvuMUdERJgPHTpk8/HuvPNOc2hoqLmystJsNpvNtbW15urqapuYo0ePmjt37mz+zW9+Y93myNcEAAC4D/dbZzT1fqsxBw4cMAcEBJhvvPFGs8lksm5/+eWXzZLMf/7zn81ms9lcXV1t7tixo3nQoEHm06dPW+PefPNNsyTzddddd8FcXnnlFbMk84cffmjdZjKZzJdeeqn52muvtW6z3MvVN2nSJHNQUJD51KlTNtcmyfzqq682et31c3LGfaE93zv23rcCvoYpjYAPeuWVV/Txxx/bPNauXdsg7o477lCHDh2srxMSEiRJP/zwgyTp4MGD+vzzz/Wb3/xGl112mc2xBoNBkmQymfTRRx8pJSVFvXr1su6PiIjQmDFj9MUXX6i8vFyS9P7772vIkCE2fbLCwsKsQ8ctPv74Yx07dkx33XWXDh06ZH34+/tr8ODB1mHfZWVl+vrrrzVu3DiFhoZaj//FL36hK664wuHP25gxY5Sbm6uamhrl5OTI399fv/rVrxrEmc1mLV++XL/85S9lNpttcrzpppt0/PhxFRQUSJL8/f2t/Rvq6up05MgR1dbWauDAgdaY+i70NQEAAJ6B+62m3W815pNPPlFNTY0efPBB+fn97y3qxIkTFRISojVr1kiStm7dqsOHD2vixIlq1ep/k5XGjh1r8zk+nzvuuEOtW7e2mdb42Wefac+ePTafo/oj4ioqKnTo0CElJCSosrJSxcXFNh/TaDTq7rvvvuC5m/u+0J7vHUfuWwFfw5RGwAddc801djVRPfs/Rst/qEePHpX0v/9Mz7eM9MGDB1VZWanLL7+8wb6YmBjV1dVp9+7d6tevn3bu3Gkdbl/f2ceWlJRIknVq4dlCQkIkSTt37pQk9enTp9GP6eh/3nfeeaemTp2qtWvX6q233lJSUpKCg4MbxB08eFDHjh3Ta6+9ptdee63Rj3XgwAHr8yVLlmjevHkqLi7W6dOnrdsbW9npQl8TAADgGbjfatr9VmMs5zg7x4CAAPXq1cu63/Lv2SthtmrVyjr98kI6duyom266SStWrNCrr76qNm3a6O2331arVq1s+rZ+9913evTRR7Vu3TprMdHi+PHjNq8vvfRSuxvUN+d9ob3fO47ctwK+hIIX0ILV71tQn9lsdnEmtixNVf/617+qS5cuDfbX/4tec4qIiFBiYqLmzZunjRs3nnNlRkt+6enpGjduXKMxP/vZzyRJS5cu1fjx45WSkqJp06YpPDxc/v7+ys7O1o4dOxoc56lfEwAA0DSe+n+7u+63PEF6erpWr16t1atX67bbbtPy5ct14403KiwsTJJ07NgxXXfddQoJCdEf//hHRUVFqU2bNiooKNAf/vCHBgsANNYfrTHuuC905L4V8DW++1sMwEWzDJkvLCw8Z0xYWJiCgoL0/fffN9hXXFwsPz8/de/eXZLUo0cP618T6zv72KioKElSeHi4brjhhnOeu0ePHpJk18e015gxYzRhwgS1b99et956a6MxYWFhCg4OlslkOm9+kpSTk6NevXopNzfXOrRckp544okm5QcAAHxLS7zfOtc5vv/+e5spmzU1Nfrxxx+t+Vnitm/fruHDh1vjamtrVVpaanfh5rbbblNwcLDefvtttW7dWkePHrWZzrhhwwYdPnxYubm5+vnPf27d/uOPPzb9ItX894X2fu/Ye98K+Bp6eAE4p7CwMP385z/Xn//8Z+3atctmn+UvS/7+/rrxxhu1atUqlZaWWvfv379fb7/9toYNG2YdEn/rrbdq8+bN+vLLL61xBw8e1FtvvWXzsW+66SaFhIRo1qxZNkO96x8jnRmRddVVV2nJkiU2Q8s//vhj/ec//2nSNaelpemJJ57QggULzjk03d/fX6NGjdLy5csbvcGw5GeJlWz/Evevf/1LmzZtalJ+AADAt7TE+62z3XDDDQoICNCLL75oc8/0xhtv6Pjx4xo5cqQkaeDAgerYsaNef/111dbWWuPeeusth9o/BAYG6le/+pXef/99LVy4UG3btlVycrJ1f2P3bzU1NVqwYEGTr/FcH/di7gvt/d6x974V8DWM8AJ80Nq1axs005Sk+Ph4m7+a2ePFF1/UsGHDFBsbq3vvvVc9e/ZUaWmp1qxZo6+//lqS9PTTT+vjjz/WsGHDNHnyZLVq1UqLFi1SdXW1nnvuOevHevjhh/XXv/5VN998s37/+99bl8nu0aOHvv32W2tcSEiIFi5cqF//+teKjY3VnXfeqbCwMO3atUtr1qzR0KFD9fLLL0uSsrOzNXLkSA0bNky/+c1vdOTIEb300kvq16+fTpw44fDnLjQ0VE8++eQF45599lmtX79egwcP1sSJE3XFFVfoyJEjKigo0CeffKIjR45IkpKSkpSbm6tf/epXGjlypH788Ue9+uqruuKKK5qUHwAA8Azcbzl2v3Xw4EE9/fTTDbb37NlTY8eOVVZWlmbOnKmbb75Zt912m77//nstWLBAgwYNUnp6uqQzPb2efPJJPfDAAxoxYoRuv/12lZaW6s0331RUVJTNqKkLSU9P11/+8hd9+OGHGjt2rNq2bWvdFx8frw4dOmjcuHH63e9+J4PBoL/+9a8XPQ3VGfeF9nzv2HvfCvgc1y8MCcBZzrdMtiTz4sWLzWbz/5Y6njNnToOPIcn8xBNP2GwrLCw0/+pXvzK3b9/e3KZNG/Pll19ufuyxx2xiCgoKzDfddJO5Xbt25qCgIPPw4cPN//znPxt8/G+//dZ83XXXmdu0aWO+9NJLzU899ZT5jTfesFkm22L9+vXmm266yRwaGmpu06aNOSoqyjx+/Hjz1q1bbeKWL19ujomJMRuNRvMVV1xhzs3NNY8bN65Zlsm25CHJ/O6779ps379/v/n+++83d+/e3dy6dWtzly5dzNdff735tddes8bU1dWZZ82aZe7Ro4fZaDSar776avPq1asb5Ofo1wQAALgH91tNu9861+fr+uuvt8a9/PLL5ujoaHPr1q3NnTt3Nt93333mo0ePNvh4L774ovXe6pprrjFv3LjRHBcXZ7755psvmItFbW2tOSIiwizJ/P777zfYv3HjRvOQIUPMgYGB5q5du5offvhh84cffmiWZF6/fr3NtZ3rXvK6664zX3fdddbXzrovtOd7x577VsDXGMxmOiEDAAAAALxTXV2dwsLClJqaqtdff93d6QDwEPTwAgAAAAB4hVOnTjWYWviXv/xFR44cUWJionuSAuCRGOEFAAAAAPAKGzZs0EMPPaTRo0erY8eOKigo0BtvvKGYmBjl5+efc9EhAC0PTesBAAAAAF4hMjJS3bt314svvqgjR47okksu0f/93//p2WefpdgFwAYjvAAAAAAAAOBT6OEFAAAAAAAAn0LBCwAAAAAAAD7Fo3t41dXVae/evQoODpbBYHB3OgAAwEuYzWZVVFSoa9eu8vPj73ueiPs8AADQFPbe53l0wWvv3r3q3r27u9MAAABeavfu3erWrZu700AjuM8DAAAX40L3eR5d8AoODpZ05iJCQkLcnA0AAPAW5eXl6t69u/VeAp6H+zwAANAU9t7neXTByzK8PSQkhBshAADgMKbKeS7u8wAAwMW40H0eTS0AAAAAAADgUyh4AQAAAAAAwKdQ8AIAAAAAAIBPcWrBy2Qy6bHHHlPPnj0VGBioqKgoPfXUUzKbzc48LQAAAAAAAFowpzatnz17thYuXKglS5aoX79+2rp1q+6++26Fhobqd7/7nTNPDQAAAAAAgBbKqQWvf/7zn0pOTtbIkSMlSZGRkVq2bJm+/PJLZ54WAAAAAAAALZhTpzTGx8fr008/1bZt2yRJ33zzjb744gvdcsstjcZXV1ervLzc5gEAAAAAAAA4wqkjvKZPn67y8nJFR0fL399fJpNJzzzzjMaOHdtofHZ2tmbOnOnMlAAAAAAAAODjnDrC6+9//7veeustvf322yooKNCSJUs0d+5cLVmypNH4rKwsHT9+3PrYvXu3M9MDAAAAAACAD3LqCK9p06Zp+vTpuvPOOyVJAwYM0M6dO5Wdna1x48Y1iDcajTIajc5MCQAAAAAAAD7OqQWvyspK+fnZDiLz9/dXXV2dM08LAAAASJJqamq0YMEC7dixQ1FRUZo8ebICAgLcnRYAAHAypxa8fvnLX+qZZ57RZZddpn79+umrr77S/Pnz9Zvf/MaZpwUAAAD08MMPa/78+TKZTNZtU6dOVUZGhp577jk3ZgYAAJzNqQWvl156SY899pgmT56sAwcOqGvXrpo0aZIef/xxZ54WAAAALdzDDz+sOXPmNNhuMpms2yl6AQDguwxms9ns7iTOpby8XKGhoTp+/LhCQkLcnQ4AAPAS3EN4Pmd+jWpqatSmTRud7zbXYDDo1KlTTG8EAMDL2HsP4dQRXgAA96msrFRxcXGj+6qqqlRaWqrIyEgFBgY22B8dHa2goCBnpwgATvHiiy+et9glSWazWS+++KKmTp3qoqwAAIArUfACAB9VXFysuLi4Jh2bn5+v2NjYZs4IAFwjJyfH7jhvLHiZTCbl5eWprKxMERERSkhIkL+/v7vTAgDAo1DwAgAfFR0drfz8/Eb3FRUVKT09XUuXLlVMTEyjxwKAt/r666+bNc6T5ObmKjMzU6WlpdZtkZGRmjdvnlJTU92XGAAAHoaCFwD4qKCgoAuO0oqJiWEkFwCfU11d3axxniI3N1dpaWm69dZblZycrKqqKgUGBmr79u1KS0tTTk4ORS8AAP6LghcAAADg4UwmkzIzM9WrVy998MEHMplM1n3+/v7q1auXpk6dquTkZKY3AgAgCl4AAACAx8vLy7OZxlifyWTSjh07rHGJiYmuSwwAAA/l5+4EAAAAAJzf7t27mzUOAABfR8ELAAAAXq+yslIFBQUqKChw6LiCggJVVlY6Kavmk5eXZ30eHh6u119/XWVlZXr99dcVHh7eaBwAAC0ZUxoBAADg9YqLixUXF+fwcXFxccrPz/f4BTw2btwoSfLz89Pu3bsVEBAgSZowYYL+7//+T4GBgaqrq7PGAQDQ0jHCCwAAAF4vOjpa+fn5ys/Pd+i4/Px8RUdHOymr5nPw4EFJUl1dndLS0rRp0yZVVFRo06ZNSktLU11dnU0cAAAtHSO8AAAA4PWCgoKso7RKSkrUp0+fCx5TUlKi3r17Ozu1JqusrFRxcbEkKTg4WAcPHlSrVq20detWxcfHW+MiIiLUqlUr1dbWKjg4WAUFBYqOjlZQUJC7UgcAwO0oeAEAAMCn9O7dWwaDQWaz+ZwxBoPBo4tdUuPTNGtra1VWVmazrf7rH374wWumaQIA4ExMaQQAAECTvfLKK4qMjFSbNm00ePBgffnll+5OSdKZqX8Gg6HRfQaDwToF0JPVn6a5adOmC8YbDAZt2rTJa6ZpAgDgTBS8AAAA0CR/+9vflJGRoSeeeEIFBQW68sorddNNN+nAgQPuTk3SmaJXSUmJWrduLUlq3bq1SkpKvKLYJf1vmmZsbKyGDBmiadOmnTd+6tSpGjJkiGJjY5nOCABo8Sh4AQAAoEnmz5+viRMn6u6779YVV1yhV199VUFBQfrzn//s7tSsevfurc2bN0uSNm/e7PHTGM/nueee07Rp0+Tv72+z3d/fX9OmTdNzzz3npswAAPA89PACAACAw2pqapSfn6+srCzrNj8/P91www12Tb9D0zz33HN6+umnlZWVpfnz5ysjI0PZ2dkKCAhwd2otVv3FBeqrqqpSaWmpIiMjFRgY2OixLC4AAM5DwQsAAAAOO3TokEwmkzp37myzvXPnzo2++a+urlZ1dbX1dXl5udNz9FUBAQEaO3as5s+fr7Fjx1LscrPGFhewF4sLAIDzUPACAACA02VnZ2vmzJnN8rFKSkpUUVFhd3xRUZHNv/YKDg5Wnz59HDoGLY9lcYGzFRUVKT09XUuXLlVMTMw5jwUAOAcFLwAAADisU6dO8vf31/79+22279+/X126dGkQn5WVpYyMDOvr8vJyde/e3eHzlpSUqG/fvo4nLCk9Pd3hY7Zt20bRC+dlWVzgXGJiYhjFBQBuQMELAAAADgsICFBcXJw+/fRTpaSkSDqzKuKnn36qKVOmNIg3Go0yGo0XfV7LyK7zjZo5mz29lM5mGZ3jyEgyAADgOSh4AQAAoEkyMjI0btw4DRw4UNdcc41eeOEFnTx5UnfffbfTz+3oqJmhQ4c6MRsAAOBpKHgBAACgSe644w4dPHhQjz/+uPbt26errrpKH3zwQYNG9s2tSzuDAo9tk/b6Oe0cgce2qUs7g9M+PgAAcC4KXgAAAGiyKVOmNDqF0ZkmxQUo5vNJ0ufOO0fMf8/jCo424ZdoxA8AwIVQ8AIAAIBXWZRfozsef1MxTlzhrqi4WIvmjdFtTjvDGRfThF+iET8AAOdCwQsAAABeo7KyUvtOmLXxhxOqal9n1zFNalpfZtK+E+aLSdUuTWnCL9GIHwCAC6HgBQAAAK9RXFwsSZo4caJLzhccHOyS8zjahF+iET8AAOdDwQsAAABeIyUlRZIUHR2toKAgu46xjGxydBSVq/pduaIJv0QjfgBAy0LBCwAAAF6jU6dOmjBhQpOObcooKldwRRN+ybWN+AEAcDcKXgAAAIAbuaIJv+S6RvwAAHgCCl4AAACAG+07YVZV+75S16ucep6qfXUuacQPAIAnoOAFAAAAuEllZaUkqaCgwKHjmrpKIwAALQUFLwAAAMBNXL3qpOS6lScBAHAnCl4AAADwepWVldbi0dksI5vONcLJkRUfm1tTVp2UPH/lSQAA3M3pBa89e/boD3/4g9auXavKykr17t1bixcv1sCBA519agAAALQQxcXFiouLO29Menp6o9vz8/Pdtnrjxaw6KXnuypMAALibUwteR48e1dChQzV8+HCtXbtWYWFhKikpUYcOHZx5WgAAALQw0dHRys/Pb3TfhfpdRTt5dUQAAOB6Ti14zZ49W927d9fixYut23r27OnMUwIAAKAFCgoKOu9Ip6FDh7owGwAA4G5+zvzg//jHPzRw4ECNHj1a4eHhuvrqq/X666+fM766ulrl5eU2DwAAAAAAAMARTi14/fDDD1q4cKH69OmjDz/8UPfdd59+97vfacmSJY3GZ2dnKzQ01Pro3r27M9MDAAAAAACAD3Jqwauurk6xsbGaNWuWrr76at17772aOHGiXn311Ubjs7KydPz4cetj9+7dzkwPAAAAAAAAPsipBa+IiAhdccUVNttiYmK0a9euRuONRqNCQkJsHgAAAAAAAIAjnNq0fujQofr+++9ttm3btk09evRw5mkBAAAAr1dZWani4uJG9xUVFdn8e7bo6GgFBQU5LTcAADydUwteDz30kOLj4zVr1izdfvvt+vLLL/Xaa6/ptddec+ZpAQAAAK9XXFysuLi488akp6c3uj0/P/+8q1YCAODrnFrwGjRokFasWKGsrCz98Y9/VM+ePfXCCy9o7NixzjwtAAAA4PWio6OVn5/f6L6qqiqVlpYqMjJSgYGBjR4LAEBL5tSClyQlJSUpKSnJ2acBAAAAfEpQUNB5R2kNHTrUhdkAAOBdnF7wAgAAAAB4h/P1jrvQyEKJ/nEAPAcFLwAAAACAJPt6x50P/eMAeAoKXgAAAAAASefvHVdUVKT09HQtXbpUMTEx5zweADwBBS8AAAAAbmMymZSXl6eysjJFREQoISFB/v7+7k6rxbpQ7zhJiomJYRQXAI/n5+4EAAAAALRMubm56t27t4YPH64xY8Zo+PDh6t27t3Jzc92dGgDAy1HwAgAAAOByubm5SktL04ABA7Rp0yZVVFRo06ZNGjBggNLS0ih6AQAuCgUvAAAAAC5lMpmUmZmppKQkrVy5UkOGDFG7du00ZMgQrVy5UklJSZo6dapMJpO7UwUAeCkKXgAAAABcKi8vT6WlpZoxY4bMZrM2bNigZcuWacOGDTKbzcrKytKPP/6ovLw8d6cKAPBSNK0HAAAA4FJlZWWSpB07dujOO+/Uzp07rft69OihZ555xiYOAABHUfACAAAA4FIRERGSpPT0dAUGBtrsO3DggNLT023iAABwFFMaAQAAALhUfHy8/PzO/1bEz89P8fHxLsoIAOBrKHgBAADAYc8884zi4+MVFBSk9u3buzsdeJm8vDzV1dVJktq2bavExERdd911SkxMVNu2bSVJdXV19PACADQZUxoBAADgsJqaGo0ePVrXXnut3njjDXenAy+zbt06SVJQUJAOHTqkDRs22OwPCgpSZWWl1q1bp+uvv94NGQIAvB0FLwAAADhs5syZkqQ333zTvYnAK+3evVuSVFlZ2eh+y3ZLHAAAjmJKIwAAAACX6tKlS7PGAQBwNkZ4AQAAwOmqq6tVXV1tfV1eXu7GbOBuhYWFzRoHAMDZGOEFAAAASdL06dNlMBjO+yguLm7Sx87OzlZoaKj10b1792bOHt5k06ZNzRoHAMDZGOEFAACczmQyKS8vT2VlZYqIiFBCQoL8/f3dnRbOkpmZqfHjx583plevXk362FlZWcrIyLC+Li8vp+jVgtk7wo+RgACApqLgBQAAnCo3N1eZmZkqLS21bouMjNS8efOUmprqvsTQQFhYmMLCwpzysY1Go4xGo1M+NryPwWBo1jgAAM7GlEYAAOA0ubm5SktL04ABA7Rp0yZVVFRo06ZNGjBggNLS0pSbm+vuFNFEu3bt0tdff61du3bJZDLp66+/1tdff60TJ064OzV4gTZt2jRrHAAAZ2OEFwAAHsZXpv+ZTCZlZmYqKSlJK1eulJ/fmb+zDRkyRCtXrlRKSoqmTp2q5ORkr7y+lu7xxx/XkiVLrK+vvvpqSdL69euVmJjopqzgLYKDg3Xy5Em74gAAaApGeAEA4EFyc3PVu3dvDR8+XGPGjNHw4cPVu3dvrxwJlZeXp9LSUs2YMcNa7LLw8/NTVlaWfvzxR+Xl5bkpQ1yMN998U2azucGDYhfscezYsWaNAwDgbIzwAgDAQ1im/yUlJWnZsmXq37+/CgsLNWvWLKWlpSknJ8erel6VlZVJkvr379/ofst2SxyAlqOurq5Z4wDAE1VWVja6unFVVZVKS0sVGRmpwMDARo+Njo5WUFCQs1P0aRS8AADwAL44/S8iIkKSVFhYqCFDhjTYX1hYaBMHwPdZ3vy1bt1aNTU1F4xv3bq1CgoKJPHmD4D3KS4uVlxcXJOOzc/PV2xsbDNn1LJQ8ALcxFd69ABoHpbpf8uWLTvn9L/4+Hjl5eV5zZSxhIQERUZGatasWVq+fLk2btxo/Z03dOhQZWdnq2fPnkpISHB3qgBcxNE3fydPnrTG8+YPgLeJjo5Wfn5+g+1FRUVKT0/X0qVLFRMTc85jcXEoeAFukJubq8zMTJWWllq3RUZGat68eV41XQlA8/HF6X/+/v6aN2+eRo0apeDgYFVXV1v3GY1GVVdXa/ny5RT7gRbE8ubvr3/9q1544YULxj/44IP69a9/bT0WALxJUFDQeQv1MTExFPKdiKb1gItZevQMGDBAmzZtUkVFhTZt2qQBAwYoLS3NKxtTA7h49af/Ncbbp//VL3Y19hpAy2B58zd79uwGo1nP5ufnp9mzZys2NlaxsbFMZwQAOISCF+BCZ/foGTJkiNq1a2ft0ZOUlKSpU6fKZDK5O1UALlZ/+t/p06e1YcMGLVu2TBs2bNDp06e9cvqfyWTS3XffLUkKDw/X1KlTtWDBAk2dOlXh4eGSpLvvvpvfeUALFBAQoMzMTEmSwWCw2Wd5nZmZqYCAAJfnBgDwDUxpBFzIF3v0AGge9af/hYaGqqqqyrovMDBQVVVVXjf979NPP1V5ebkuueQS7dmzR61a/e+2Izs7W507d9aRI0f06aef6sYbb3RjpgDc4bnnnpMkzZ8/36bw7efnp4yMDOt+AACaghFegAv5Yo8eAM3r7JEOlm2Nbfd0f/3rXyVJM2fOtCl2SVKrVq30xBNP2MQBaHmee+45VVZWKiMjQ5KUkZGhyspKil0AgItGwQtwIV/v0QOg6epPeT5y5Iief/55TZkyRc8//7wOHz7slVOeT5w4IUnq2bNno/sjIyNt4gC0TAEBARo7dqwkaezYsUxjBAA0C6Y0Ai5Uv0fPypUrbaY11tXVeWWPHgDNwzLledKkSYqOjtbOnTut+1544QVNmjRJ7733nldNeR42bJhWrlypGTNm6JZbbmnwO+/RRx+1xgGApyspKVFFRYXd8UVFRTb/2is4OFh9+vRx6BgAQEMUvAAXsvToSUtLU0pKirKystS/f38VFhYqOztbq1evVk5Ojlf16AHQPCxTmbOyshQYGGiz78CBA5oxY4ZNnDd44IEH9PDDD+vbb79VUlKS+vTpo1OnTqlNmzYqKSnRv//9b/n5+emBBx5wd6oAcF4lJSXq27dvk45NT093+Jht27ZR9AKAi+Sygtezzz6rrKws/f73v9cLL7zgqtMCHic1NVU5OTnKzMxUfHy8dXvPnj2Vk5Oj1NRUN2YHwF0sqxZK0vXXX69HHnnEWhB/5plntHr16gZxns6yCtucOXO0du1arV27tkEMq7AB8AaWkV1Lly5VTEyMXcdUVVWptLRUkZGRDf6QcS5FRUVKT093aCQZAKBxLil4bdmyRYsWLdLPfvYzV5wO8HipqalKTk5WXl6eysrKFBERoYSEBEZ2AS2YpTfXJZdcohUrVlibvA8ZMkQrVqxQeHi4jh496lU9vADA18TExCg2Ntbu+KFDhzoxGwDA+Ti9af2JEyc0duxYvf766+rQoYOzTwd4DX9/fyUmJuquu+5SYmIixS4PZTKZtGHDBi1btkwbNmyg2ACnycvLkyQdOXJEqamp2rRpkyoqKrRp0yalpqbq6NGjNnHeoKamRvPmzZOkBqO4LK/nzZunmpoal+cGAAAA3+b0gtf999+vkSNH6oYbbnD2qeDDampq9MILL+iBBx7QCy+8wJsjuERubq6ioqI0fPhwjRkzRsOHD1dUVJRyc3PdnRp82JNPPql///vfio+PV0hIiOLj41VYWKgnnnjC3ak57KWXXlJdXZ0k6cYbb7Qp4t14442SzjSvf+mll9yZJgAAAHyQUwte77zzjgoKCpSdnW1XfHV1tcrLy20ewMMPP6y2bdvqoYce0ssvv6yHHnpIbdu21cMPP+zu1ODDcnNzNWrUKO3fv99m+/79+zVq1CiKXmh2lpUXP/nkExUVFen555/XlClT9Pzzz+s///mPPvnkE5s4b2AZjTZo0CDl5ubq1KlTeu+993Tq1Cnl5uZq0KBBNnEAAABAc3FaD6/du3fr97//vT7++GO1adPGrmOys7M1c+ZMZ6UEL/Twww9rzpw56ty5s55++mklJSVp9erVevTRRzVnzhxJ0nPPPefmLJvGZDLRw8tDmUwm/fa3v5V0phBfn+X1fffdp+TkZL5mHsIXfp4SExMVHh6uL774Qh06dNCpU6es+7KysnTq1CmFh4d7VcGrsrJSkhQREaE+ffpo586d1n09evRQ//79beIAAACA5uK0EV75+fk6cOCAYmNj1apVK7Vq1UqfffaZXnzxRbVq1arRPjhZWVk6fvy49bF7925npQcvUFNTo+eff16dO3fWTz/9pAkTJqhLly6aMGGCfvrpJ3Xu3FnPP/+8V05vzM3NVe/evW2myvXu3dvrRw35Sr+rDRs26ODBg5KksLAw3X777br77rt1++23KywsTJJ04MABbdiwwY1ZwsJXfp78/f01btw4SbIpdtV/PW7cOK8q5MXFxUmS/vGPf6isrMxmX1lZmdasWWMTBwAAADQXpxW8rr/+ev373//W119/bX0MHDhQY8eO1ddff93oDbvRaFRISIjNAy3XggULVFtbq6efftq6WplFq1at9Mc//lG1tbVasGCBmzJsmtzcXKWlpWnAgAE2/WwGDBigtLQ0r3uTbuErRQdJ1qljRqNRhw8f1t///nctXrxYf//733X48GEZjUabOLiP5eepsamn3vbzZDKZtGTJEklqsHy95fWSJUu8qpA8fPhw6/Oz/zhR/3X9OAAAAKA5OK3gFRwcrP79+9s8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bcqQXldg1BrQPHyxyA8AAADf1JReaxfzx1pn9Vqj4CXpxIkTysjIkCRlZGRo9erVateunZuz8m2+WBzyRb44ag1wB18s8gMW1dXVGjx4sL755ht99dVXuuqqq9ydEgAAaAaOvvf2tD5rLb7gdc0112jLli3W15999pmCg4M1aNAgffnll27MDHA/XyxMMk0T7uCLP0uAxcMPP6yuXbvqm2++cXcqAAAAVi264HV2sau+LVu26JprrvHKoteePXs0fPhwSdLw4cP1n//8R5deeqmbswI8A9M0AaD5rF27Vh999JGWL1+utWvXujsdAAAAqxZb8Dpx4sQ5i10WW7Zs0YkTJ7xqeqPRaFRNTY31dXl5ubp166aAgABVV1e7MTPAMzBNEwCax/79+zVx4kStXLnS7t+nAAAArtKiCl6VlZXW0R2TJk2y65jhw4dr0aJFDr05dpezi1311dTUyGg0UvRCi8fUMs/XlGmnElNPXY3pwS2b2WzW+PHj9dvf/lYDBw5UaWnpBY+prq62uQ8pLy93YoYAmqr+e6azWX4nn+93sze8bwLQMrSogldxcbHi4uIcOmbr1q2Ki4tTfn6+R77RtfyHtGfPnnMWuyxqamr03nvvWac38p8RAE/EiobegenBvmn69OmaPXv2eWOKior00UcfqaKiQllZWXZ/7OzsbM2cOfNiUwTgZPa8Z0pPTz/nPk993wSg5WlRBa/o6Gjl5+dLkkOFr/z8fEVHRzsrrYviaBHvtttusz7nPyMAnqgp004lpp66GtODfVNmZqbGjx9/3phevXpp3bp12rRpk4xGo82+gQMHauzYsVqyZEmD47KysqyrYktnRnh17969WfIG0Hzqv2c6mz0jdT31fROAlqdFFbyCgoKaVODx5KKQ5T8kRwt4lmMBwNNczLRTiamnrsL0YN8UFhamsLCwC8a9+OKLevrpp62v9+7dq5tuukl/+9vfNHjw4EaPMRqNDQpkADzPhd4zDR061IXZAEDTtaiCly9qShGPNxkAAOBiXHbZZTavLQv8REVFqVu3bu5ICQAAwIafuxMAAAAAAAAAmhMjvAAAAHBRIiMjZTab3Z0GAMALdGlnUOCxbdJe546/CTy2TV3aGZx6Dni2Flvw8vPzU11dnV1xAAAAAADg4k2KC1DM55Okz517npj/ngstV4steLVu3VrV1dV2xXkD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",
      "text/plain": [
       "<Figure size 1500x500 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "encoded_mean, encoded_log_var, encoded_z = encoder(train_tensor)\n",
    "\n",
    "# set figure size\n",
    "plt.figure(figsize=(15, 5))\n",
    "# boxplot of encoded_mean\n",
    "plt.subplot(1, 2, 1)\n",
    "plt.boxplot(encoded_mean.numpy().reshape(-1, latent_filter))\n",
    "plt.title('Encoded Mean')\n",
    "\n",
    "# boxplot of encoded_log_var\n",
    "plt.subplot(1, 2, 2)\n",
    "plt.boxplot(encoded_log_var.numpy().reshape(-1, latent_filter))\n",
    "plt.title('Encoded Log Variance')\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Generate Data\n",
    "\n",
    "Use the trained model to generate new time series data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1, 4566, 6)"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "start_date = '1974-01-01'\n",
    "end_date = '2023-12-31 23:00:00'\n",
    "dt = pd.date_range(start=start_date, end=end_date, freq='h')\n",
    "\n",
    "gen_seasonal_inputs = fourier((dt.dayofyear[::4*24]-1)/365)[np.newaxis]\n",
    "gen_seasonal_inputs.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "TensorShape([1, 4566, 10])"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "_, _, z_gen = seasonal_prior(gen_seasonal_inputs)\n",
    "z_gen.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1, 438336)"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "gen_mean = decoder(z_gen).numpy()\n",
    "noise = np.random.normal(size=gen_mean.shape)*np.exp(0.5*vae.noise_log_var[0].numpy())\n",
    "gen = gen_mean #+ noise\n",
    "gen.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1974-01-01 00:00:00    40.482704\n",
       "1974-01-01 01:00:00    38.221806\n",
       "1974-01-01 02:00:00    36.132202\n",
       "1974-01-01 03:00:00    32.789696\n",
       "1974-01-01 04:00:00    31.906300\n",
       "                         ...    \n",
       "2023-12-31 19:00:00    64.512405\n",
       "2023-12-31 20:00:00    58.124634\n",
       "2023-12-31 21:00:00    56.781807\n",
       "2023-12-31 22:00:00    54.241039\n",
       "2023-12-31 23:00:00    52.967545\n",
       "Freq: h, Length: 438288, dtype: float32"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "gen_series = pd.Series(gen[0, :len(dt)]*18.29 + 75.08, index=dt)\n",
    "gen_series"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [],
   "source": [
    "gen_series.to_csv('data/processed/generated.csv')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
